package com.context.annotation;

import com.beans.annotation.AnnotatedGenericBeanDefinition;
import com.beans.annotation.AnnotationScopeMetadataResolver;
import com.beans.annotation.ScopeMetadataResolver;
import com.beans.factory.BeanDefinitionHolder;
import com.beans.factory.BeanDefinitionReaderUtils;
import com.beans.factory.BeanDefinitionRegistry;
import com.beans.factory.BeanNameGenerator;
import com.core.env.Environment;
import com.core.env.StandardEnvironment;

import java.lang.annotation.Annotation;
import java.util.function.Supplier;

public class AnnotatedBeanDefinitionReader {

    private final BeanDefinitionRegistry registry;

    private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();

    private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
        this.registry = registry;
//        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, getOrCreateEnvironment(registry));
    }


    public void register(Class<?>... annotatedClasses) {
        for (Class<?> annotatedClass : annotatedClasses) {
            registerBean(annotatedClass);
        }
    }

    public void registerBean(Class<?> annotatedClass) {
        doRegisterBean(annotatedClass, null, null, null);
    }


    <T> void doRegisterBean(Class<T> annotatedClass, Supplier<T> instanceSupplier, String name,
                            Class<? extends Annotation>[] qualifiers) {

        // 将 Bean 配置类信息转成 AnnotatedGenericBeanDefinition
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);

        // 设置回调
//        abd.setInstanceSupplier(instanceSupplier);

        // 解析bean作用域(单例或者原型)，如果有@Scope注解，则解析@Scope，没有则默认为singleton
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);

        // 填充作用域, 初始值为空，赋为默认值 singleton
        abd.setScope(scopeMetadata.getScopeName());

        // 生成 bean 配置类 beanName
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        // 通用注解解析到abd结构中，主要是处理Lazy, primary DependsOn, Role ,Description这五个注解
//        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//        if (qualifiers != null) {
//            for (Class<? extends Annotation> qualifier : qualifiers) {
//                if (Primary.class == qualifier) {
//                    abd.setPrimary(true);
//                }
//                else if (Lazy.class == qualifier) {
//                    abd.setLazyInit(true);
//                }
//                else {
//                    abd.addQualifier(new AutowireCandidateQualifier(qualifier));
//                }
//            }
//        }

        //自定义bean注册，通常用在applicationContext创建后，手动向容器中一lambda表达式的方式注册bean,
        //比如：applicationContext.registerBean(UserService.class, () -> new UserService());
//        for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
//            customizer.customize(abd);
//        }

        // 根据 beanName 和 bean deanDefinition 装一个 beanhold
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

        // 创建代理对象
        // 暂不实现
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

        // 注册 beanDefinition 到 map 中
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }


    private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
//        if (registry instanceof EnvironmentCapable) {
//            return ((EnvironmentCapable) registry).getEnvironment();
//        }
        return new StandardEnvironment();
    }

}
